﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Threading;

using System.Windows.Navigation;
using System.ComponentModel;
using System.Windows.Media.Imaging;
using Microsoft.Xna.Framework.Media;
using Classes;
using System.Windows.Controls.Primitives;
using System.IO.IsolatedStorage;
using Scoreloop.CoreSocial.API.Model;

namespace MemoBoss
{

    public enum DifficultyLevel
    {
        Easy = 0,
        Medium = 1,
        Hard = 2,
        MemoBoss = 3,
    }

    public partial class GameScreen : UserControl
    {
        Action returnMethod;
        Action SetBackgroundPicture;
        public GameScreen(Action callback, Action SetBGPicture)
        {
            this.InitializeComponent();
            if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                SetBackgroundPicture = SetBGPicture;
                returnMethod = callback;
                this._onOff = string.Empty;
                this.createCards();
                this.InitializeEvents();
            }

        }
        private string _onOff;
        private int _levelGoodCount;
        public DispatcherTimer _gameTimer;
        private bool ArchivementIsShowing
        {
            get;
            set;
        }


        private int levelCardsCount;
        private int CardsCount
        {
            get;
            set;
        }

        private Card FlippedCard
        {
            get;
            set;
        }

        private int GoodMatch
        {
            get;
            set;
        }

        private bool HasLockedCard
        {
            get;
            set;
        }

        public bool IsClockTicking
        {
            get;
            set;
        }

        public bool IsFlawless
        {
            get;
            set;
        }

        public bool IsGameOver
        {
            get;
            set;
        }

        private bool IsPlaying
        {
            get;
            set;
        }

        public Card LastLock
        {
            get;
            set;
        }

        private int LevelMovesCount
        {
            get;
            set;
        }

        public int MaxTime
        {
            get;
            set;
        }

        public int Multiplier
        {
            get;
            set;
        }

        private int Score
        {
            get;
            set;
        }

        public int WrongCount
        {
            get;
            set;
        }




        //private void DoRandom()
        //{
        //    if (this.CardsCount > 2)
        //    {
        //        if (!this.HasLockedCard)
        //        {
        //            int num = (new Random()).Next(1, 10);
        //            if (num >= 4)
        //            {
        //                List<Card> strs = new List<Card>();
        //                for (int i = 0; i < 36; i++)
        //                {
        //                    Card card = cards[i / 6, i % 6];
        //                    //Card card = (Card)base.FindName(string.Concat("card", i.ToString()));
        //                    if (card.Opacity >= 1 && card.Visibility != Visibility.Collapsed && !card.Flipping)
        //                    {
        //                        strs.Add(card);
        //                    }
        //                }
        //                if (strs.Count != 0)
        //                {
        //                    // CurrentApplication.Instance.PlaySoundEffect("dink");
        //                    num = (new Random()).Next(0, strs.Count - 1);
        //                    this.LastLock = strs[num];
        //                    this.LastLock.SealCard();
        //                    this.HasLockedCard = true;
        //                    return;
        //                }
        //                else
        //                {
        //                    return;
        //                }
        //            }
        //            else
        //            {
        //                return;
        //            }
        //        }
        //        else
        //        {
        //            return;
        //        }
        //    }
        //    else
        //    {
        //        this.HasLockedCard = false;
        //        if (this.LastLock != null)
        //        {
        //            Card card1 = this.LastLock;
        //            if (card1.Opacity > 0)
        //            {
        //                card1.UnsealCard();
        //            }
        //        }
        //        return;
        //    }
        //}

        private void GameOver()
        {
            this.Multiplier = 1;
            //CurrentApplication.Instance.StopEffects();
            //CurrentApplication.Instance.PlaySoundEffect("over", true);
            is_running = 0;
            gameState = GameState.GameOver;
            //Cumulonimbus.Instance["running_game"].DefaultRow["score"].IntValue = this.Score;
            //if (Cumulonimbus.Instance["options"].DefaultRow["nickname"].Text.ToLower() != "textbox")
            //{
            //    this._playerNickname.Text = Cumulonimbus.Instance["options"].DefaultRow["nickname"].Text;
            //}
            //else
            //{
            //    Cumulonimbus.Instance["options"].DefaultRow["nickname"].Text = string.Empty;
            //}
            //Row row = new Row();
            //row.Cells["Id"].IntValue = -1;
            //row.Cells["score"].IntValue = this.Score;
            //Cumulonimbus.Instance["scores"].AddRow(row);
            //Cumulonimbus.Instance["scores"].DataStore = Cumulonimbus.Instance["scores"].DataStore.SortByColumn("score", false).Take(5);
            //if (Cumulonimbus.Instance["scores"].Rows.GetRowAtSpecificIndex(0)["score"].IntValue != this.Score)
            //{
            //    this._finalScore.Visibility = Visibility.Collapsed;
            //}
            //else
            //{
            //    int score = this.Score;
            //    this._finalScore.Text = string.Concat(score.ToString("#,###"), " points! Share your score!");
            //    this._finalScore.Visibility = Visibility.Visible;
            //}

            double _levelGoodCountDBL = _levelGoodCount;
            double LevelMovesCountDBL = LevelMovesCount;
            double levelCardsCountDBL = levelCardsCount;

            double performance = ((_levelGoodCountDBL - (LevelMovesCountDBL - _levelGoodCountDBL)) / (LevelMovesCountDBL == 0 ? 1 : LevelMovesCountDBL)) * (levelCardsCountDBL / 2) / 18;
            if (performance > overalBestPerformance)
            {
                overalBestPerformance = performance;
                overalBestPerformanceLevel = currentLevel;
            }

            this.IsGameOver = true;
            // this.SetGameOverVisibility(Visibility.Visible);

            int score = this.Score;
            ScoreHelper.SaveHighScore(currentDifficultyLevel, score);
            int highScore = ScoreHelper.GetHighScore(currentDifficultyLevel);



            Score scor = SubmitScore(score, currentDifficultyLevel, currentLevel);
            showGameOverPopup(scor, highScore, currentDifficultyLevel);
            SoundFX.PlaySoundEffect(SFX.EndBell);
            //MessageBox.Show("over");
        }

        Score SubmitScore(int score, DifficultyLevel currentDifficultyLevel, int levelReached)
        {
            int mode = 0;
            switch (currentDifficultyLevel)
            {
                case DifficultyLevel.Easy:
                    mode = 0;
                    break;
                case DifficultyLevel.Medium:
                    mode = 1;
                    break;
                case DifficultyLevel.Hard:
                    mode = 2;
                    break;
                case DifficultyLevel.MemoBoss:
                    mode = 3;
                    break;
            }
            var scoreController = App.slClient.CreateScoreController();

            scoreController.RequestFailed += (sender, e) =>
            {
                //Debug.WriteLine
                //    ("Score submission failed with error: " + e.Error);
            };
            scoreController.ScoreSubmitted += (sender, e) =>
            {

                //Debug.WriteLine
                //    ("Brawo! Score submitted!");
            };
            // create a score with value 100.0 for 0-mode:

            var SLscore = scoreController.CreateScore(score, 0, mode, levelReached, null);
            // and send it to the server:
            scoreController.Submit(SLscore);
            return SLscore;
        }


        Popup GameOverPopup;
        GameOverDialog GameOverDiag;
        private void showGameOverPopup(Score score, int highScore, DifficultyLevel diff)
        {
            SuspendLayout();
            if (GameOverPopup == null)
            {
                GameOverPopup = new Popup();


            }
            GameOverDiag = new GameOverDialog(GameOverDialogCallback, score, highScore, overalGoodMatchCount, overalWrongMatchCount, overalBestPerformance, overalBestPerformanceLevel, diff);
            GameOverPopup.Child = GameOverDiag;




            GameOverPopup.IsOpen = true;
            GameOverDiag.Opacity = 0;
            GameOverDiag.UpdateLayout();
            GameOverPopup.VerticalOffset = (App.Current.RootVisual as FrameworkElement).ActualHeight / 2 - GameOverDiag.ActualHeight / 2;

            GameOverPopup.HorizontalOffset = (App.Current.RootVisual as FrameworkElement).ActualWidth / 2 - GameOverDiag.ActualWidth / 2;

            GameOverDiag.Opacity = 1;
            CardsPanel.Visibility = System.Windows.Visibility.Collapsed;

        }
        void GameOverDialogCallback(bool result)
        {

            if (result)
            {
                if (GameOverPopup != null)
                    GameOverPopup.IsOpen = false;
                ReleaseLayout();

                this.Hide.Begin();
                returnMethod();
            }
            else
            {


                if (GameOverPopup != null)
                    GameOverPopup.IsOpen = false;
                ReleaseLayout();
                CardsPanel.Visibility = System.Windows.Visibility.Visible;
                Restart();



            }

        }

        public DifficultyLevel currentDifficultyLevel = DifficultyLevel.Easy;
        int currentLevel = 1;
        private int GetPoints()
        {
            int num = 5;
            DifficultyLevel gameDifficultyLevel = currentDifficultyLevel;
            switch (gameDifficultyLevel)
            {
                case DifficultyLevel.Easy:
                    {
                        num = 5;
                        break;
                    }
                case DifficultyLevel.Medium:
                    {
                        num = 15;
                        break;
                    }
                case DifficultyLevel.Hard:
                    {
                        num = 45;
                        break;
                    }
                case DifficultyLevel.MemoBoss:
                    {
                        num = 70;
                        break;
                    }
            }
            int intValue = currentLevel;
            int points = num * intValue;
            if (this.Multiplier <= 0)
            {
                points = points + 10 * this.GoodMatch * intValue;
            }
            else
            {
                points = points + 10 * (int)Math.Pow(2, (double)this.Multiplier) * this.GoodMatch * intValue;
            }
            return points;
        }


        public enum GameState
        {
            Playing = 0,
            Loading = 1,
            Paused = 2,
            GameOver = 3,
        }

        GameState gameState;

        public void HoldPlay()
        {
            if (gameState == GameState.GameOver) return;
            //while (gameState == GameState.Loading) System.Threading.Thread.Sleep(100);
            if (gameState == GameState.Playing)
            {
                elapsedTime += DateTime.Now - StartTime.Value;
                this._gameTimer.Stop();
                this.IsPlaying = false;
            }
            gameState = GameState.Paused;


        }

        private void InitializeEvents()
        {
            //this.ShowOneTimeMessage.Completed += (OnShowOneTimeMessageCompleted);
            this.GameTextSB.Completed += (OnShowOneTimeMessageCompleted);
            this.ShowCards.Completed += (OnShowCardsCompleted);
            //this.ShowCards_Fast.Completed += (OnShowCardsCompleted);
            //this.ShowCards_Medium.Completed += (OnShowCardsCompleted);
            //this.ShowCards_Slow.Completed += (OnShowCardsCompleted);
            //this.ShowCards_Blink.Completed += (OnShowCardsCompleted);
            //this.ShowCards_VeryFast.Completed += (OnShowCardsCompleted);
            this._gameTimer = new DispatcherTimer();
            this._gameTimer.Interval = TimeSpan.FromSeconds(0.1);
            this._gameTimer.Tick += OnGameTimerTick;
            //this._postingBar.Visibility = Visibility.Collapsed;
            //this._playerNickname.Visibility = Visibility.Collapsed;
            //this._playerNickname.MouseLeftButtonDown += (OnChangeNicknameClick);
            //this._nicknameBox.KeyDown += (OnNickNameKeyDown);
            //this._gameOverRect.MouseLeftButtonDown += (OnGameOverRectClick);
            //this._nicknameBox.Visibility = Visibility.Collapsed;
            //this.ShowArchivement.Completed += (OnShowArchivementsCompleted);
        }
        Storyboard ShowCards;
        Card[,] cards;
        private void createCards()
        {
            CardsPanel.Children.Clear();
            cards = new Card[6, 6];

            ShowCards = new Storyboard();
            CardsPanel.Resources.Add("ShowCards", ShowCards);
            for (int i = 0; i < 6; i++)
            {
                for (int k = 0; k < 6; k++)
                {
                    Card card = new Card();
                    card.BeforeCardFlip += new EventHandler(OnBeforeCardFlip);
                    card.CardFlipped += new EventHandler(OnCardFlipped);
                    card.GoodMatchDone += new EventHandler(OnGoodMatchDone);
                    Grid.SetRow(card, i);
                    Grid.SetColumn(card, k);
                    cards[i, k] = card;

                    CardsPanel.Children.Add(card);

                    DoubleAnimation da = new DoubleAnimation();
                    da.BeginTime = TimeSpan.FromMilliseconds(i * k * 10);
                    da.Duration = TimeSpan.FromSeconds(1);
                    da.From = 0;
                    da.To = 1;
                    ShowCards.Children.Add(da);
                    Storyboard.SetTarget(da, card);



                    // Set the attached properties of Canvas.Left and Canvas.Top
                    // to be the target properties of the two respective DoubleAnimations



                    Storyboard.SetTargetProperty(da, new PropertyPath(Card.OpacityProperty));
                }
            }
        }
        private void InitLevel(int level)
        {

            List<string> item;
            this._levelGoodCount = 0;
            this.IsFlawless = true;
            this.WrongCount = 0;
            this.LevelMovesCount = 0;
            this.FlippedCard = null;
            this.IsPlaying = false;
            this.IsGameOver = false;
            this.IsClockTicking = false;
            if (level >= 3)
            {
                this.GoodMatch = 0;
            }

            if (Classes.LevelHelper.Levels.ContainsKey(level))
            {
                item = Classes.LevelHelper.Levels[level];
            }
            else
            {
                item = Classes.LevelHelper.Levels.ElementAt(Classes.LevelHelper.Levels.Count - 1).Value;
            }

            //item.Add("0	0	1	1	0	0");
            //item.Add("0	0	1	1	0	0");
            //item.Add("0	0	1	1	0	0");
            //item.Add("0	0	1	1	0	0");
            //item.Add("0	0	1	1	0	0");
            //item.Add("0	0	1	1	0	0");
            // CurrentApplication.Instance.StopEffects();
            //if (!Cumulonimbus.Instance.VolatileStorage.ContainsKey(level.ToString()))
            //{
            //    int count = Cumulonimbus.Instance.VolatileStorage.Count;
            //    item = (List<string>)Cumulonimbus.Instance.VolatileStorage[count.ToString()];
            //}
            //else
            //{
            //    item = (List<string>)Cumulonimbus.Instance.VolatileStorage[level.ToString()];
            //}

            int length = 0;
            foreach (string str in item)
            {
                length = length + str.Replace("0", string.Empty).Length;
            }
            levelCardsCount = length;
            this.CardsCount = length;
            int[] strs = this.Shuffle(length);
            int num = 0;
            int num1 = 0;
            int num2 = (new Random(Environment.TickCount)).Next(1, 6);
            //ImageSource bitmapImage = new BitmapImage(new Uri(string.Concat(CurrentApplication.Instance.BaseImageSource, "cards/cover", num2.ToString(), ".png"), UriKind.RelativeOrAbsolute));
            int row = 0;
            var ml = new Microsoft.Xna.Framework.Media.MediaLibrary();
            using (var pictures = ml.Pictures)
            {
                foreach (string str1 in item)
                {
                    //char[] chrArray = new char[1];
                    //chrArray[0] = '\t';
                    //string[] strArrays = str1.Split(chrArray);
                    char[] strArrays1 = str1.ToCharArray();
                    for (int i = 0; i < (int)strArrays1.Length; i++)
                    {
                        //char str2 = ;
                        Card card = cards[row, i];

                        //(Card)base.FindName(string.Concat("card", num.ToString()));
                        //card.UnsealCard();
                        if (strArrays1[i] != '0')
                        {
                            card.Opacity = 0;
                            card.Visibility = Visibility.Visible;
                            card.Locked = false;
                            card.Reset.Begin();
                            //card._cardCover.Source = bitmapImage;
                            Picture pic;

                            if (App.SettingsInstance.UseAllImagesSetting)
                            {
                                pic = pictures[strs[num1]];
                            }
                            else
                            {
                                KeyValuePair<int, int> pict = App.collection.PicturesCollection.ElementAt(strs[num1]);
                                pic = pictures[pict.Value];
                                if (pic.GetHashCode() != pict.Key)
                                {
                                    pic = pictures.First(p => p.GetHashCode() == pict.Key);
                                }

                            }

                            //pictures[strs[num1]];//pictures.Single(p => p.GetHashCode() == strs[num1].Key && p.Name == strs[num1].Value);
                            BitmapImage bi = new BitmapImage();
                            bi.CreateOptions = BitmapCreateOptions.BackgroundCreation;//BitmapCreateOptions.BackgroundCreation;
                            bi.SetSource(pic.GetThumbnail());


                            card._cardImage.Source = bi;

                            card.ImageId = strs[num1];
                            num1++;
                        }
                        else
                        {
                            card.Visibility = Visibility.Collapsed;
                        }
                        num++;
                    }
                    row++;
                }
            }

            //for (int i = 0; i < 6; i++)
            //{
            //    bool RowHasCards = false;
            //    for (int k = 0; k < 6; k++)
            //    {
            //        if (cards[i, k].Visibility == System.Windows.Visibility.Visible ) RowHasCards = true;
            //    }
            //    if (!RowHasCards) 
            //        CardsPanel.RowDefinitions[i].Height = GridLength.Auto;
            //    else 
            //        CardsPanel.RowDefinitions[i].Height = new GridLength(1, GridUnitType.Star);
            //}
            //for (int i = 0; i < 6; i++)
            //{
            //    bool ColHasCards = false;
            //    for (int k = 0; k < 6; k++)
            //    {
            //        if (cards[k, i].Visibility == System.Windows.Visibility.Visible) ColHasCards = true;
            //    }
            //    if (!ColHasCards)
            //        CardsPanel.ColumnDefinitions[i].Width = GridLength.Auto;
            //    else
            //        CardsPanel.ColumnDefinitions[i].Width = new GridLength(1, GridUnitType.Star);
            //}

            elapsedTime = new TimeSpan(0);
            AllocatedTime = levelAllocationDefault;
            switch (currentDifficultyLevel)
            {
                case DifficultyLevel.Easy:
                    AllocatedTime = levelAllocationDefault;
                    break;
                case DifficultyLevel.Medium:
                    AllocatedTime = TimeSpan.FromSeconds(levelAllocationDefault.TotalSeconds * 0.75);
                    break;
                case DifficultyLevel.Hard:
                    AllocatedTime = TimeSpan.FromSeconds(levelAllocationDefault.TotalSeconds * 0.5);
                    break;
                case DifficultyLevel.MemoBoss:
                    AllocatedTime = TimeSpan.FromSeconds(levelAllocationDefault.TotalSeconds * 0.25);
                    break;
            }
            if (level <= 25)
            {
                AllocatedTime = AllocatedTime + TimeSpan.FromSeconds(2 * (level - 1));
            }
            else
            {
                AllocatedTime = AllocatedTime + TimeSpan.FromSeconds(2 * 26 - 5 * (level - 25));
            }

            if (level == 25)
            {
                string unlock_setting = "";
                switch (currentDifficultyLevel)
                {
                    case DifficultyLevel.Easy:
                        if (!App.Difficulty_Hard_Unlocked) unlock_setting = "Difficulty_Hard_Unlocked";
                        break;
                    case DifficultyLevel.Medium:
                        if (!App.Difficulty_MemoBoss_Unlocked) unlock_setting = "Difficulty_MemoBoss_Unlocked";
                        break;

                }
                if (unlock_setting != "")
                {
                    lock (App.settingsOperationLock)
                    {
                        if (IsolatedStorageSettings.ApplicationSettings.Contains(unlock_setting))
                        {
                            IsolatedStorageSettings.ApplicationSettings[unlock_setting] = true;
                        }
                        else
                        {
                            IsolatedStorageSettings.ApplicationSettings.Add(unlock_setting, true);
                        }
                        IsolatedStorageSettings.ApplicationSettings.Save();
                    }
                    if (unlock_setting == "Difficulty_Hard_Unlocked")
                    {
                        App.Difficulty_Hard_Unlocked = true;
                        MessageBox.Show("You have unlocked Hard difficulty mode. Good job!");
                    }
                    if (unlock_setting == "Difficulty_MemoBoss_Unlocked")
                    {
                        App.Difficulty_MemoBoss_Unlocked = true;
                        MessageBox.Show("You have unlocked Memo Boss difficulty mode! Nothing's gonna stop you now!!!");
                    }
                }
            }
             //AllocatedTime = TimeSpan.FromSeconds(5);
            ShowGameText(string.Format("Level {0}", level));
        }

        TimeSpan levelAllocationDefault = TimeSpan.FromSeconds(60);
        //private void MainMenu()
        //{
        //    base.NavigationService.GoBack();
        //}

        private void NextLevel()
        {
            int score = this.Score;
            ScoreHelper.SaveHighScore(currentDifficultyLevel, score);
            int highScore = ScoreHelper.GetHighScore(currentDifficultyLevel);



            SubmitScore(score, currentDifficultyLevel, currentLevel);

            //Cell item = Cumulonimbus.Instance["running_game"].DefaultRow["level"];
            SetBackgroundPicture();
            currentLevel = currentLevel + 1;

            this.InitLevel(currentLevel);
            //this.UpdateGameScreen();
        }

        //private void OnBackButtonClick(object sender, MouseButtonEventArgs e)
        //{
        //    if (this._gameOver.Opacity == 1)
        //    {
        //        this.MainMenu();
        //        return;
        //    }
        //    else
        //    {
        //        return;
        //    }
        //}

        //protected override void OnBackKeyPress(CancelEventArgs e)
        //{
        //    //base.OnBackKeyPress(e);
        //    e.Cancel = true;
        //    NavigationService.GoBack();
        //}

        private void OnBeforeCardFlip(object sender, EventArgs e)
        {
            if (this.IsPlaying)
            {
                DateTime now = DateTime.Now;
                if (now.Second % 2 != 0)
                {
                    SoundFX.PlaySoundEffect(SFX.CardFlip1);
                }
                else
                {
                    SoundFX.PlaySoundEffect(SFX.CardFlip2);
                }
                ((Card)sender).FlipCard();
            }
        }

        private void OnCardFlipped(object sender, EventArgs e)
        {
            if (!this.IsGameOver)
            {
                Card card = (Card)sender;
                if (this.FlippedCard != null)
                {
                    if (this.FlippedCard.ImageId != card.ImageId)
                    {

                        _onOff = string.Concat(_onOff, "0");

                        LevelMovesCount = LevelMovesCount + 1;
                        int intValue = 0;
                        DifficultyLevel gameDifficultyLevel = currentDifficultyLevel;
                        switch (gameDifficultyLevel)
                        {
                            case DifficultyLevel.Easy:
                                {
                                    intValue = 0;
                                    break;
                                }
                            case DifficultyLevel.Medium:
                                {
                                    intValue = 2;
                                    break;
                                }
                            case DifficultyLevel.Hard:
                                {
                                    intValue = 5;
                                    break;
                                }
                            case DifficultyLevel.MemoBoss:
                                {
                                    intValue = 6;
                                    break;
                                }
                        }

                        intValue = intValue + currentLevel - 1;
                        //TODO: time bonuses

                        //if (intValue > 10)
                        //{
                        //    intValue = 10;
                        //}
                        //if (intValue <= 0)
                        //{
                        //    intValue = 1;
                        //}

                        //if (this._Timer.Value <= (double)intValue)
                        //{
                        //    this._Timer.Value = 0;
                        //}
                        //else
                        //{
                        //    ProgressBar @value = this._Timer;
                        //    @value.Value = @value.Value - (double)intValue;
                        //}

                        this.Multiplier = -1;
                        this.IsFlawless = false;

                        WrongCount = WrongCount + 1;
                        if (WrongCount > overalWrongMatchCount) overalWrongMatchCount = WrongCount;

                        this.GoodMatch = 0;
                        this.FlippedCard.MatchCard(false);
                        card.MatchCard(false);

                        SoundFX.PlaySoundEffect(SFX.CardFlipBack);

                        this.FlippedCard = null;
                        //this.Archive(false);
                        // this.DoRandom();
                        return;
                    }
                    else
                    {

                        _onOff = string.Concat(_onOff, "1");

                        GoodMatch = GoodMatch + 1;
                        if (GoodMatch > overalGoodMatchCount) overalGoodMatchCount = GoodMatch;

                        _levelGoodCount = _levelGoodCount + 1;
                        this.WrongCount = 0;

                        Score = Score + this.GetPoints();
                        this.UpdateGameScreen();
                        int num = 2 * currentLevel;
                        if (num > 5)
                        {
                            num = 5;
                        }

                        //TODO: time bonus
                        //if (this._Timer.Value + (double)num < this._Timer.Maximum)
                        //{
                        //    ProgressBar progressBar = this._Timer;
                        //    progressBar.Value = progressBar.Value + (double)num;
                        //}
                        //else
                        //{
                        //    this._Timer.Value = this._Timer.Maximum;
                        //}


                        int num1 = 0;
                        DifficultyLevel difficultyLevel = currentDifficultyLevel;
                        switch (difficultyLevel)
                        {
                            case DifficultyLevel.Easy:
                                {
                                    num1 = 4;
                                    break;
                                }
                            case DifficultyLevel.Medium:
                                {
                                    num1 = 6;
                                    break;
                                }
                            case DifficultyLevel.Hard:
                                {
                                    num1 = 7;
                                    break;
                                }
                            case DifficultyLevel.MemoBoss:
                                {
                                    num1 = 8;
                                    break;
                                }
                        }
                        if (this.Multiplier < num1)
                        {

                            Multiplier = Multiplier + 1;
                        }
                        if (this.Multiplier > 0)
                        {
                            double num2 = Math.Pow(2, (double)this.Multiplier);
                            //this._scoreMultiplier.Text = string.Concat("x", num2.ToString());
                            //CurrentApplication.Instance.PlaySoundEffect("phew");
                            //this.ShowMultiplier.Begin();
                        }
                        this.FlippedCard.MatchCard(true);
                        card.MatchCard(true);

                        SoundFX.PlaySoundEffect(SFX.CardVanish);

                        this.FlippedCard = null;

                        CardsCount = CardsCount - 2;

                        LevelMovesCount = LevelMovesCount + 1;
                        //this.Archive(false);
                        //this.DoRandom();
                        return;
                    }
                }
                else
                {
                    this.FlippedCard = card;
                    return;
                }
            }
            else
            {
                return;
            }
        }

        //private void OnChangeNicknameClick(object sender, MouseButtonEventArgs e)
        //{
        //    if (this._postScoreRect.Visibility != Visibility.Collapsed)
        //    {
        //        this._playerNickname.Visibility = Visibility.Collapsed;
        //        this._nicknameBox.Text = this._playerNickname.Text;
        //        this._nicknameBox.Visibility = Visibility.Visible;
        //        this._nicknameBox.SelectionStart = 0;
        //        this._nicknameBox.SelectionLength = this._nicknameBox.Text.Length;
        //        this._nicknameBox.Focus();
        //        return;
        //    }
        //    else
        //    {
        //        return;
        //    }
        //}

        //private void OnGameOverRectClick(object sender, MouseButtonEventArgs e)
        //{
        //    this._nicknameBox.Visibility = Visibility.Collapsed;
        //    if (this._nicknameBox.Text.Trim() != string.Empty)
        //    {
        //        this._playerNickname.Text = this._nicknameBox.Text.Trim();
        //        if (this._playerNickname.Text.Length > 45)
        //        {
        //            this._playerNickname.Text = this._playerNickname.Text.Substring(0, 44);
        //        }
        //        Cumulonimbus.Instance["options"].DefaultRow["nickname"].Text = this._playerNickname.Text;
        //    }
        //    this._playerNickname.Visibility = Visibility.Visible;
        //}
        TimeSpan AllocatedTime;
        DateTime? StartTime;
        DateTime? EndTime;
        TimeSpan elapsedTime = new TimeSpan(0);
        public TimeSpan GameTimeRemaining
        {
            get
            {
                // if the game hasnt started then the time is 0
                if (StartTime == null)
                    return new TimeSpan(0, 0, 0);

                // if the game is over then use that, if not then use now                
                if (EndTime == null)
                {
                    return AllocatedTime - elapsedTime - (DateTime.Now - StartTime.Value);
                }

                return AllocatedTime - elapsedTime - (EndTime.Value - StartTime.Value);
            }
        }

        private void OnGameTimerTick(object sender, EventArgs e)
        {
            TimeSpan rem = GameTimeRemaining;
            if (rem <= TimeSpan.FromSeconds(0))
            {
                this.TimeIsUp();
            }
            else
            {
                timerTransform.ScaleX = rem.TotalSeconds / AllocatedTime.TotalSeconds;
                //TimeSpan remaining = (AllocatedTime - GameTimeElapsed);
                txtElapsed.Text = rem.ToString(@"mm\:ss\.ff");
            }

            //if (this._Timer.Value <= 0)
            //{
            //    this.TimeIsUp();
            //}
            //else
            //{
            //    ProgressBar @value = this._Timer;
            //    @value.Value = @value.Value - 1;
            //    if (this._Timer.Value <= 30 && !this.IsClockTicking)
            //    {
            //        this.IsClockTicking = true;
            //        //CurrentApplication.Instance.PlaySoundEffect("clock", false);
            //        return;
            //    }
            //}
        }

        int currentScore;
        int elapsed;
        private void OnGoodMatchDone(object sender, EventArgs e)
        {
            if (!this.IsGameOver)
            {
                if (this.CardsCount == 0)
                {
                    this.HoldPlay();
                    gameState = GameState.Loading;


                    //int asd = (_levelGoodCount / (WrongCount == 0 ? 1 : WrongCount * (levelCardsCount / 2))) * (levelCardsCount / 2);
                    double _levelGoodCountDBL = _levelGoodCount;
                    double LevelMovesCountDBL = LevelMovesCount;
                    double levelCardsCountDBL = levelCardsCount;

                    double performance = ((_levelGoodCountDBL) / (LevelMovesCountDBL == 0 ? 1 : LevelMovesCountDBL)) * (levelCardsCountDBL / 2) / 18;
                    if (performance > overalBestPerformance)
                    {
                        overalBestPerformance = performance;
                        overalBestPerformanceLevel = currentLevel;
                    }
                    //score.Score = score.Score + (int)this._Timer.Value * currentLevel * this.GoodMatch;
                    //TODO:check 
                    Score = Score + (int)(GameTimeRemaining).TotalSeconds * currentLevel * this.GoodMatch;
                    //this.Archive(true);
                    //Cell item = Cumulonimbus.Instance["running_game"].DefaultRow["score"];
                    currentScore = currentScore + this.Score;
                    //Cell intValue = Cumulonimbus.Instance["running_game"].DefaultRow["elapsed"];
                    elapsed = elapsed - 15;
                    if (elapsed < 60)
                    {
                        elapsed = 120;
                    }
                    this.MaxTime = elapsed;

                    int score = this.Score;
                    this.txtScore.Text = score.ToString("#,##0");

                    this.NextLevel();
                    //this.Play();
                }
                return;
            }
            else
            {
                return;
            }
        }

        //private void OnMSAdControlLayoutChanged(object sender, EventArgs e)
        //{
        //    if (this._msAdControl.Visibility == Visibility.Collapsed)
        //    {
        //        this._msAdControl.LayoutUpdated -= (OnMSAdControlLayoutChanged);
        //        this._adDuplexControl.Visibility = Visibility.Visible;
        //        this.LayoutRoot.Children.Remove(this._msAdControl);
        //    }
        //}

        //protected override void OnNavigatedFrom(NavigationEventArgs e)
        //{
        //    //if (this._Timer != null)
        //    //{
        //    //    this._Timer.IsEnabled = false;
        //    //}
        //    if (this._gameTimer != null)
        //    {
        //        this._gameTimer.Stop();
        //    }
        //    base.OnNavigatedFrom(e);
        //}

        //protected override void OnNavigatedTo(NavigationEventArgs e)
        //{
        //    base.OnNavigatedTo(e);
        //    if ( Classes.LevelHelper.Levels ==null) Classes.LevelHelper.load();

        //    // CurrentApplication.Instance.CurrentState = CurrentState.ShowingSubPage;

        //    //if (this._gameOverRect.Visibility != Visibility.Visible)
        //    //{
        //    //    if (!this.IsGameOver)
        //    //    {
        //    //        this.StartGame();
        //    //    }
        //    //    this.InitializeAdvertising();
        //    //    return;
        //    //}
        //    //else
        //    //{
        //    //    return;
        //    //}
        //    this.StartGame();
        //}

        //private void OnNickNameKeyDown(object sender, KeyEventArgs e)
        //{
        //    if (e.Key == Key.Enter)
        //    {
        //        this.OnGameOverRectClick(null, null);
        //    }
        //}



        private void OnShowCardsCompleted(object sender, EventArgs e)
        {
            foreach (UIElement child in this.CardsPanel.Children)
            {
                if (child as Card == null || ((Card)child).Visibility != Visibility.Visible)
                {
                    continue;
                }
                ((Card)child).FlipBack.Begin();
            }

            SoundFX.PlaySoundEffect(SFX.CardFlipBack);

            if (gameState != GameState.Paused)
                Play();
            else
                showPausePopup();
        }

        private void OnShowOneTimeMessageCompleted(object sender, EventArgs e)
        {
            //CurrentApplication.Instance.PlaySoundEffect("shuffle");
            //this._messageShadow.Visibility = Visibility.Collapsed;
            //this._messageText.Visibility = Visibility.Collapsed;
            UpdateGameScreen();
            int intValue = currentLevel;
            DifficultyLevel gameDifficultyLevel = currentDifficultyLevel;
            this.ShowCards.Begin();
            ShowCardsPanel();

            //switch (gameDifficultyLevel)
            //{
            //    case DifficultyLevel.Easy:
            //        {
            //            if (intValue <= 10)
            //            {
            //                if (intValue <= 6)
            //                {
            //                    this.ShowCards_Slow.Begin();
            //                    return;
            //                }
            //                else
            //                {
            //                    this.ShowCards_Medium.Begin();
            //                    return;
            //                }
            //            }
            //            else
            //            {
            //                this.ShowCards_Fast.Begin();
            //                return;
            //            }
            //        }
            //    case DifficultyLevel.Normal:
            //        {
            //            if (intValue <= 10)
            //            {
            //                if (intValue <= 6)
            //                {
            //                    this.ShowCards_Medium.Begin();
            //                    return;
            //                }
            //                else
            //                {
            //                    this.ShowCards_Fast.Begin();
            //                    return;
            //                }
            //            }
            //            else
            //            {
            //                this.ShowCards_VeryFast.Begin();
            //                return;
            //            }
            //        }
            //    case DifficultyLevel.Hard:
            //        {
            //            if (intValue <= 10)
            //            {
            //                if (intValue <= 6)
            //                {
            //                    this.ShowCards_Fast.Begin();
            //                    return;
            //                }
            //                else
            //                {
            //                    this.ShowCards_VeryFast.Begin();
            //                    return;
            //                }
            //            }
            //            else
            //            {
            //                this.ShowCards_Blink.Begin();
            //                return;
            //            }
            //        }
            //    case DifficultyLevel.VeryHard:
            //        {
            //            this.ShowCards_Blink.Begin();
            //            this._Timer.Maximum = 20;
            //            return;
            //        }
            //    default:
            //        {
            //            return;
            //        }
            //}
        }

        private void ShowGameText(string text)
        {
            this._messageText.Text = text;
            this._messageText.Visibility = Visibility.Visible;
            this.GameTextSB.Begin();
            SoundFX.PlaySoundEffect(SFX.RingBell);
        }

        //private void OnTryAgainClick(object sender, MouseButtonEventArgs e)
        //{
        //    if (this._gameOver.Opacity == 1)
        //    {
        //        this._finalScore.Visibility = Visibility.Collapsed;
        //        this.HideGameOverMessage();
        //        this.StartGame();
        //        return;
        //    }
        //    else
        //    {
        //        return;
        //    }
        //}
        public void GameSceenOnNavigatedTo() 
        {
            if (gameState == GameState.GameOver) 
            {
                GameOverDiag.OnNavigatedTo();
            }
        }


        public void Pause()
        {
            HoldPlay();
            if (gameState == GameState.GameOver) return;
            if (ShowCards.GetCurrentState() != ClockState.Active)
            {
                if (GameTextSB.GetCurrentState() != ClockState.Active)
                {
                    showPausePopup();

                }
                else
                {
                    //GameTextSB.Pause();
                }
                return;
            }
            //CurrentApplication.Instance.StopEffects();
        }

        private void Play()
        {
            StartTime = System.DateTime.Now;
            gameState = GameState.Playing;
            this.IsPlaying = true;
            this._gameTimer.Start();
        }

        private void Restart()
        {
            ClearGameScreen();
            this.StartGame();
        }

        private void Resume()
        {
            this.Play();
        }




        private int[] Shuffle(int playboard)
        {

            //var ml = new Microsoft.Xna.Framework.Media.MediaLibrary();

            ////var albums = from pict in ml.Pictures where App.collection.AlbumCollection.ContainsKey(pict.Album.GetHashCode()) select pict;

            //using (var pictures = ml.Pictures)
            //{
            //    var pics = pictures.Where(x => App.collection.AlbumCollection.ContainsKey(x.Album.GetHashCode())).ToList();
            //}

            this._onOff = string.Empty;
            int[] strArrays = new int[playboard];
            List<int> nums = new List<int>();
            //Dictionary<int, string> usableCards = App.collection.PicturesCollection.ToDictionary(entry => entry.Key,
            //                                   entry => entry.Value);
            int totalCards;

            if (App.SettingsInstance.UseAllImagesSetting)
            {
                var ml = new Microsoft.Xna.Framework.Media.MediaLibrary();
                using (var pictures = ml.Pictures)
                {
                    totalCards = ml.Pictures.Count;
                }
            }
            else
            {
                totalCards = App.collection.PicturesCollection.Count;
            }


            List<int> usableCards = new List<int>();
            for (int i = 0; i < totalCards; i++)
            {
                usableCards.Add(i);
            }

            for (int i = 0; i < playboard; i++)
            {
                nums.Add(i);
            }
            DateTime now = DateTime.Now;
            Random random = new Random(now.Millisecond);
            while (playboard > 0)
            {

                int num = random.Next(0, usableCards.Count - 1);
                int item = usableCards.ElementAt(num);
                usableCards.Remove(item);
                int num1 = random.Next(0, nums.Count - 1);
                int item1 = nums[num1];
                nums.RemoveAt(num1);
                int num2 = random.Next(0, nums.Count - 1);
                while (Math.Abs(num2 - num1) == 1 && playboard > 2)
                {
                    num2 = random.Next(0, nums.Count - 1);
                }
                int item2 = nums[num2];
                nums.RemoveAt(num2);
                strArrays[item1] = item;
                strArrays[item2] = item;
                playboard = playboard - 2;
            }
            return strArrays;
        }
        int overalGoodMatchCount;
        int overalWrongMatchCount;
        double overalBestPerformance;
        int overalBestPerformanceLevel;

        int is_running;
        private void StartGame()
        {
            overalGoodMatchCount = 0;
            overalWrongMatchCount = 0;
            overalBestPerformance = 0;
            overalBestPerformanceLevel = 0;

            gameState = GameState.Loading;
            if (is_running == 0)
            {
                is_running = 1;
                currentScore = 0;
                elapsed = 120;
                currentLevel = 1;
            }
            this.Multiplier = -1;
            this.Score = currentScore;
            this.GoodMatch = 0;
            this.IsPlaying = false;
            //this.HideGameOverMessage();

            this.InitLevel(currentLevel);
            this.UpdateGameScreen();
            //  this.Play();

        }

        private void TimeIsUp()
        {
            this.HoldPlay();
            this.GameOver();
        }

        //private void UnlockImages(string badgekey, string container)
        //{
        //    foreach (Row row in Cumulonimbus.Instance[container].Rows)
        //    {
        //        if (row["badge"].Text != badgekey)
        //        {
        //            continue;
        //        }
        //        row["Obtained"].IntValue = 1;
        //    }
        //}

        private void UpdateGameScreen()
        {
            this.txtLevel.Text = string.Format("Level: {0}", currentLevel);
            int score = this.Score;
            this.txtScore.Text = score.ToString("#,##0");
            if (!this.IsPlaying)
            {
                txtElapsed.Text = TimeSpan.FromSeconds(0).ToString(@"mm\:ss\.ff");
                timerTransform.ScaleX = 1;
            }
            if (gameState == GameState.Loading)
            {

                timerTransform.ScaleX = 1;
                txtElapsed.Text = AllocatedTime.ToString(@"mm\:ss\.ff");
            }
        }

        private void Show_Completed(object sender, EventArgs e)
        {
            UpdateGameScreen();
            SetBackgroundPicture();
            if (Classes.LevelHelper.Levels == null) Classes.LevelHelper.load();
            this.StartGame();
        }
        public void ClearGameScreen()
        {
            txtElapsed.Text = TimeSpan.FromSeconds(0).ToString(@"mm\:ss\.ff");
            this.txtLevel.Text = string.Format("Level: 1");
            this.txtScore.Text = 0.ToString("#,##0");
            timerTransform.ScaleX = 1;
            CardsPanel.Visibility = System.Windows.Visibility.Collapsed;
        }
        private void ShowCardsPanel()
        {
            CardsPanel.Visibility = System.Windows.Visibility.Visible;
        }
        private void Rectangle_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            _gameTimer.Stop();
        }

        public void ExitScreen()
        {
            if (PausePopup != null && PausePopup.IsOpen)
            {
                PauseDiag.ReturnDefault();
                return;
            }
            if (GameOverPopup != null && GameOverPopup.IsOpen)
            {
                GameOverDiag.ReturnDefault();
                return;
            }

            Pause();

            // _gameTimer.Stop();
            // this.Hide.Begin();

        }

        Popup PausePopup = null;
        PauseDialog PauseDiag;
        private void showPausePopup()
        {
            SuspendLayout();
            if (PausePopup == null)
            {
                PausePopup = new Popup();


            }
            PauseDiag = new PauseDialog(PauseCallback);
            PausePopup.Child = PauseDiag;




            PausePopup.IsOpen = true;
            PauseDiag.Opacity = 0;
            PauseDiag.UpdateLayout();
            PausePopup.VerticalOffset = (App.Current.RootVisual as FrameworkElement).ActualHeight / 2 - PauseDiag.ActualHeight / 2;

            PausePopup.HorizontalOffset = (App.Current.RootVisual as FrameworkElement).ActualWidth / 2 - PauseDiag.ActualWidth / 2;

            PauseDiag.Opacity = 1;
            CardsPanel.Visibility = System.Windows.Visibility.Collapsed;

        }
        void PauseCallback(bool result)
        {

            if (result)
            {
                if (PausePopup != null)
                    PausePopup.IsOpen = false;
                ReleaseLayout();
                _gameTimer.Stop();

                int score = this.Score;
                ScoreHelper.SaveHighScore(currentDifficultyLevel, score);
                int highScore = ScoreHelper.GetHighScore(currentDifficultyLevel);



                SubmitScore(score, currentDifficultyLevel, currentLevel);

                this.Hide.Begin();
                is_running = 0;
                returnMethod();
            }
            else
            {


                if (PausePopup != null)
                    PausePopup.IsOpen = false;
                ReleaseLayout();
                CardsPanel.Visibility = System.Windows.Visibility.Visible;
                Play();



            }

        }
        void SuspendLayout()
        {
            LayoutRoot.IsHitTestVisible = false;

        }
        void ReleaseLayout()
        {
            LayoutRoot.IsHitTestVisible = true;

        }

        //private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        //{

        //    initLayers();
        //}
    }
}